import core.*;
import fairy_tale.Maerchenwelt;
import util.RandomUtil;

import java.util.*;

public class Maerchen {

    //Now all data types have been prepared and Little Red Riding Hood can set out on the path.
    //Implement a method public ArrayList <Position> wegFinden (Position ziel). The return value
    //should be a list of all positions of Red Riding Hood so that the path can be traced later.
    public static List<Position> wegFinden = new ArrayList<>();

    public static Maerchenwelt m;

    public static  Wolf w;

    public static Baum t;

    public static Gefahr gf;

    public static  Rotkaeppchen r;

    static int count = 0;

    static int MaerchenweltX;
    static int MaerchenweltY;

    //test
    public static void main(String[] args) {
        int x,y,b,g;
        Scanner sc = new Scanner(System.in);
        System.out.println("set x");
        x = sc.nextInt();
        MaerchenweltX = x;
        if(x < 10 )
            throw new IllegalArgumentException("Enlarge the enchanted forest");

        System.out.println("set y");
        y = sc.nextInt();
        MaerchenweltY = y;
        if(y < 10 )
            throw new IllegalArgumentException("Enlarge the enchanted forest");

        System.out.println("set Tree number");
        b = sc.nextInt();
        if(b > (x*y-3))
            throw new IllegalArgumentException(" Reduce the number of trees and dangers");

        System.out.println("set Gefahr number");
        g = sc.nextInt();
        if(g > (x*y-3))
            throw new IllegalArgumentException(" Reduce the number of trees and dangers");



        r = new Rotkaeppchen(new Position(0,0));

        // oma should be created and randomly placed in the area x-8 to x-1 and y-8 to y-1 on the map
        Oma o = new Oma(new Position(RandomUtil.getOmaRandom(),RandomUtil.getOmaRandom()));
        System.out.println(" ");
        System.out.println("Oma("+ o.getPosition().getX() +","+ o.getPosition().getY()+")");

        //init wolf
        w = new Wolf(new Position(RandomUtil.getWolfRandom(x),RandomUtil.getWolfRandom(y)));

        m = new Maerchenwelt(x,y,x,y);


        //set red
        m.getKarte()[r.getPosition().getX()][r.getPosition().getY()] = r;

        //set oma
        m.getKarte()[o.getPosition().getX()][o.getPosition().getY()] = o;

        //set wolf
        setWolfValue(w.getPosition(),w,x,y);

        for(int a = 0;a < b;a++){
            t = new Baum(new Position(RandomUtil.getTreeRandom(x),RandomUtil.getTreeRandom(y)));
            setTreeValue(t.getPosition(),t,x,y);
        }

        for(int a = 0;a < g;a++){
            gf = new Gefahr(new Position(RandomUtil.getTreeRandom(x),RandomUtil.getTreeRandom(y)));
            setTreeValue(gf.getPosition(),gf,x,y);
        }

        //Initialize map
        m.printWald();

        //Little Red Riding Hood began to move
        start();
    }

    //set wolf value
    public static void setWolfValue(Position position, VerwunschenerWald o,int x,int y){
        if(position.getX() >= MaerchenweltX || position.getY() >= MaerchenweltY){
            w = new Wolf(new Position(RandomUtil.getWolfRandom(x),RandomUtil.getWolfRandom(y)));
            setWolfValue(w.getPosition(),w,x,y);
        }
        if(Objects.isNull(m.getKarte()[position.getX()][position.getY()])){
            m.getKarte()[position.getX()][position.getY()] = o;
        }else {
            w = new Wolf(new Position(RandomUtil.getWolfRandom(x),RandomUtil.getWolfRandom(y)));
            setWolfValue(w.getPosition(),w,x,y);
        }
    }

    //set Tree and Gefahr value
    public static void setTreeValue(Position position, VerwunschenerWald b,int x,int y){

        try {
            if(Objects.isNull(m.getKarte()[position.getX()][position.getY()])){
                m.getKarte()[position.getX()][position.getY()] = b;
            }else {
                t = new Baum(new Position(RandomUtil.getTreeRandom(x),RandomUtil.getTreeRandom(y)));
                setTreeValue(t.getPosition(),t,x,y);
            }
        }catch (ArrayIndexOutOfBoundsException e){
            t = new Baum(new Position(RandomUtil.getTreeRandom(x),RandomUtil.getTreeRandom(y)));
            setTreeValue(t.getPosition(),t,x,y);
        }
    }

    public static void start(){
        Scanner sc = new Scanner(System.in);
        System.out.println(" ");
        System.out.println("Please select an option");
        System.out.println("1:up 2:right 3:down 4:left 5:random 500");
        int o = sc.nextInt();
        if(o == 5){
            random();
            start();
        }else {
            execute(o);
            start();
        }

    }

    private static void execute(int o) {
        int x = r.getPosition().getX();
        int y = r.getPosition().getY();
        switch (o){
            case 1:
                //y-1
                if(check(x,y-1)){
                    r.geheHoch();
                }
                break;
            case 2:
                //x+1
                if(check(x+1,y)){
                    r.geheRechts();
                }
                break;
            case 3:
                //y+1
                if(check(x,y+1)){
                    r.geheRunter();
                }
                break;
            case 4:
                //x-1
                if(check(x-1,y)){
                    r.geheLinks();
                }
                break;
        }
        //Check Little Red Riding Hood's health
        if(r.check()){
            if(Objects.isNull(m.getKarte()[r.getPosition().getX()][r.getPosition().getY()])){
                m.getKarte()[x][y]  = null;
                m.getKarte()[r.getPosition().getX()][r.getPosition().getY()]  = r;
                wegFinden.add(new Position(r.getPosition().getX(),r.getPosition().getY()));
                count++;
                System.out.println(" ");
                System.out.println("valid path" + count);

                if(count == 500){
                    for(int a = 0;a< wegFinden.size();a++){
                        System.out.print(wegFinden.get(a).getPostion() + " ");
                    }

                    if(r.getPosition().getX() == 0 && r.getPosition().getY() == 0){
                        System.out.println(" ");
                        System.out.println("Little Red Riding Hood has returned home.");
                    }else {
                        System.out.println(" ");
                        System.out.println("Little Red Riding Hood got lost on the way home");

                        //If the last position is not the target position and Little Red Riding Hood's health status is 0.
                        if(!r.istNochLebendig()){
                            System.out.println(" ");
                            System.out.println("Little Red Riding Hood has not returned home.");
                        }
                    }

                    throw new SecurityException("main server over!");
                }

            }else {
                m.getKarte()[x][y]  = r;
                //health
                if(r.istNochLebendig()){
                    System.out.println("Little Red Riding Hood's health " + r.getGesundheit());
                }else {
                    throw new IllegalArgumentException("Little red riding hood is dead");
                }
            }
        }
        m.printWald();
    }

    private static void random() {
        for(int a = 0;a < 501;a++){
            System.out.println(" ");
            System.out.println("execute for the "+ a+" time ");
            execute(RandomUtil.getRandom(4));
        }
    }

    public static boolean check(int x,int y){
        if(x < 0 || y < 0 || x >= MaerchenweltX || y >= MaerchenweltY){
            System.out.println("You can't leave the forest");
            return false;
        }

        try {
            if(Objects.isNull(m.getKarte()[x][y])){
                if(x == 0 && y ==0){
                    System.out.println("Little red riding hood is home");
                }
                return true;
            }
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("("+ x +","+ y+")");
        }

        if(m.getKarte()[x][y] instanceof Wolf){
            r.gesundheitVerringern(r.getGesundheit() - w.getSchaden());
        }
        if(m.getKarte()[x][y] instanceof Gefahr){
            r.gesundheitVerringern(r.getGesundheit() - gf.getSchaden());
        }
        if(m.getKarte()[x][y] instanceof Oma){
            r.gesundheitVerringern(100);
            speak(r,(Oma) m.getKarte()[x][y]);
        }
        return false;
    }

    public static void speak(Rotkaeppchen r, Oma oma){
        Scanner sc = new Scanner(System.in);
        System.out.println(" ");
        System.out.println("1:Oma speak 2:Rotkaeppchen speak");
        int o = sc.nextInt();
        switch (o){
            case 1:
                System.out.println(oma.speak(r,1));
                break;
            case 2:
                System.out.println(r.speak(oma,2));
                break;
        }
    }
}
